package cn.stronglink.esm27.collection.iot.devices.algorithmservice.algorithm;

import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.sun.jna.Native;

import cn.stronglink.esm27.collection.iot.devices.algorithmservice.entity.Point;

/**
 * 濮樻柧缍嬮幍鈺傛殠缁犳纭�
 * 
 * @author yuzhantao
 *
 */
public class GasDispersionAlgorithm implements IAlgorithm {
	protected MathModelAPI api;

	protected Optional<Integer> as; // 婢堆勭毜缁嬪啿鐣炬惔锔肩礉閺佹潙鐎烽敍灞藉絿閸婏拷 1,2,3,4,5,6 娑撳骸銇囧鏃偳旂�规艾瀹抽崣鏍э拷鑹般�冮惃鍕嚠鎼存柨鍙х化锟� 1=A, 2=B, 3=C, 4=D, 5=E, 6=F
	protected Optional<Double> ws, // 閻滎垰顣ㄦ搴拷鐕傜礉娑擄拷閼割剙褰囬崷浼存桨 10m 妤傛ê顦╅惃鍕挬閸у洭顥撻柅鐕傜礉閸楁洑缍卪/s
			wd, // 妞嬪骸鎮滈敍灞藉礋娴ｅ秴瀹�
			gd, // 濮光剝鐓嬪鏂剧秼閸︺劌鐖跺〒鈺�绗呴惃鍕タ鎼达讣绱濋崡鏇氱秴 kg/m3
			h, // 濞夊嫭绱￠悙鍦瀲閸︿即娼伴惃鍕彯鎼达拷
			dq; // 濞夊嫭绱″┃鎰繁鎼达讣绱漦g/s
	protected Optional<Double> fCurrentTime; // 鐠侊紕鐣� fCurrentTime 閺冨爼妫块悙鍦畱閼煎啫娲挎潪顔肩波缁撅拷 fCurrentTime: 閹碘晜鏆庨弮鍫曟？ 鏉╂柨娲栭崐锟� true 鐠侊紕鐣婚幋鎰閿涘畺alse 鐠侊紕鐣绘径杈Е
	protected Optional<double[]> concentrations; // 鐠佸墽鐤嗗ù鎾冲闂冨牆锟借偐娈戦弫鎵矋
	// protected Optional td; // 缁夘垰鍨庨弮鍫曟？闂傛挳娈�,double

	public GasDispersionAlgorithm() {

		String filePath = GasDispersionAlgorithm.class.getResource("").getPath().replaceFirst("/","").replaceAll("%20"," ")+"MathModel.DLL";
		this.api = (MathModelAPI) Native.loadLibrary(filePath , MathModelAPI.class);
	}

	/**
	 * 閺囧瓨鏌婇崣鍌涙殶
	 */
	@Override
	public void updateParams(Object[] params) {
		Preconditions.checkNotNull(params);
		Preconditions.checkArgument(params.length >= 8);

		this.as = Optional.of((int) params[0]);
		Preconditions.checkArgument((int) this.as.get() > 0 && (int) this.as.get() < 7, "閸欐牕锟界厧绱撶敮锟�,閸欐牕锟借壈瀵栭崶锟� 1閿濓拷6閵嗭拷");
		this.ws = Optional.of((double) params[1]);
		this.wd = Optional.of((double) params[2]);
		this.gd = Optional.of((double) params[3]);
		this.h = Optional.of((double) params[4]);
		this.dq = Optional.of((double) params[5]);
		this.fCurrentTime = Optional.of((double) params[6]);
		this.concentrations = Optional.of((double[]) params[7]);
	}

	@Override
	public Object calc() {
		// 閸掓繂顫愰崠鏍吀缁犳鐨垫担鎻侾I
		int initResult = this.api.Init_API();
		Preconditions.checkArgument(initResult == 1, "閸掓繂顫愰崠鏍с亼鐠愶拷,鏉╂柨娲栭崐锟�:" + initResult);
		// 濮樻柧缍嬮幍鈺傛殠娴肩姴寮弫锟�
		this.api.SetGaussionModelParameters_API((int) as.get(), (double) ws.get(), (double) wd.get(), (double) gd.get(),
				(double) h.get(), (double) dq.get());
		// 鐠佸墽鐤嗙粔顖氬瀻閺冨爼妫块梻鎾閿涘奔绡冮崣顖欎簰娑撳秷顔曠純顔筋劃閸欏倹鏆熼敍宀�鈻兼惔蹇撳敶姒涙顓婚弰锟� 1 缁夋帪绱濋梻鎾鐡掑﹦鐓拋锛勭暬濞嗏剝鏆熺搾濠傤樋閼版妞傜搾濠囨毐閿涘矂妫块梾鏃囩Ш闂�鑳吀缁犳顐奸弫鎷岀Ш鐏忔垼锟芥妞傜搾濠傜毌閵嗭拷 dt: 缁夘垰鍨庨弮鍫曟？闂傛挳娈ч敍灞藉礋娴ｅ秶顫梥
//		this.api.SetDeltaT_API((double) td.get());
		// 瀵拷婵膩閹风噦绱濈拋锛勭暬 fCurrentTime 閺冨爼妫块悙鍦畱閼煎啫娲挎潪顔肩波缁撅拷 fCurrentTime: 閹碘晜鏆庨弮鍫曟？ 鏉╂柨娲栭崐锟� true 鐠侊紕鐣婚幋鎰閿涘畺alse 鐠侊紕鐣绘径杈Е
		boolean isSuccess = this.api.Simulate_API(this.fCurrentTime.get());
		Preconditions.checkArgument(isSuccess,"濡剝瀚欑拋锛勭暬婢惰精瑙�");
		
		List<List<Point>> result = new ArrayList<>();
		for (int i = 0; i < this.concentrations.get().length; i++) {
			// 鐠佸墽鐤嗗ù鎾冲闂冨牆锟界》绱濈拋锛勭暬濮濄倖绁挎惔锕佸瘱閸ョ鐤嗗鎾跺殠閿涘苯宕熸担宄ゞ/m3 t: 缁涘锟借偐鍤庡ù鎾冲
			this.api.SetThreshold_API(this.concentrations.get()[i]);
			// 閼惧嘲褰囨潪顔肩波缁惧潡銆婇悙鐟版綏閺嶅洦鏆熺紒鍕畱闂�鍨
			int verticesLen = this.api.GetVerticesLength_API();
			double[] datas = new double[verticesLen];
			// 閼惧嘲褰囨潪顔肩波缁惧潡銆婇悙鐟版綏閺嶅洦鏆熺紒鍒恱1,y1,z1,x2,y2,z2,......]
			this.api.GetVertices_API(datas);
			List<Point> subPointList = new ArrayList<>();
			for(int j=0;j<datas.length-2;j+=3) {
				Point point = new Point();
				point.setX(datas[j]);
				point.setY(datas[j+1]);
				point.setZ(datas[j+2]);
				subPointList.add(point);
			}
			result.add(subPointList);
		}
		return result;
	}

}
